package com.vinjogames.ui;

import java.lang.reflect.Field;

import javax.microedition.khronos.opengles.GL10;

import android.graphics.PointF;

import com.vinjogames.TankGame.R;
import com.vinjogames.entities.Game;
import com.vinjogames.gfx.Camera;
import com.vinjogames.gfx.Image;
import com.vinjogames.network.WebServiceProvider;
import com.vinjogames.util.GameConVars;
import com.vinjogames.util.Logger;

public class MapMenu {
	Game mGame;
	float mGLWidth = Camera.GL_WIDTH;
	float mGLHeight = Camera.GL_HEIGHT;

	PressableButton[] mapButtons;
	PressableButton loadOnlineMapsButton;
	PointF[] buttonLocations;
	int maxMaps = 20;

	String[] offlineMaps;
	String[] onlineMaps;

	int numOfAvailabeMaps = 0;
	
	Image mBackground;

	public MapMenu(Game game){
		mGame = game;
		mapButtons = new PressableButton[9];
		buttonLocations = new PointF[9];

		buttonLocations[0] = new PointF(1,3.5f);
		buttonLocations[1] = new PointF(4,3.5f);
		buttonLocations[2] = new PointF(7,3.5f);

		buttonLocations[3] = new PointF(1,0.5f);
		buttonLocations[4] = new PointF(4,0.5f);
		buttonLocations[5] = new PointF(7,0.5f);

		buttonLocations[6] = new PointF(2,4);
		buttonLocations[7] = new PointF(5,4);
		buttonLocations[8] = new PointF(8,4);

		
		

		/* TODO here
		 * iterate through includedMaps
		 * if !null then create a picture button (maybe generate thumb?)
		 * Display buttons
		 * On map selection get resId and pass that back to title menu, so it can start a game.
		 * TitleMenu needs to call this to display menu selection, and then return the chosen resID
		 * 
		 * also, get rid of all the maps, so no more memory is taken
		 * if online map is chosen, then pass jsonMap itself to overloaded start...hmm, titlemenu needs to expect both int or string, or just a string that it casts??
		 */
	}

	public void load(){		
		
		offlineMaps = getOfflineMaps();
		loadOnlineMapsButton = new PressableButton("Load Online Maps", new PointF(3,1), new PointF(7,2));
		
		int j = 0;
		if(offlineMaps != null){
			for(int i = 0; i < offlineMaps.length; i++){
				if(offlineMaps[i] == null) continue;
				int map = getResourceId(offlineMaps[i]);

				if(map >= 0){
					j = i;
					PointF bl = buttonLocations[j];
					PointF tr = new PointF(bl.x +2, bl.y +2);
					PressableButton button = new PressableButton(new Image(GameConVars.OFFLINE_MAP_BUTTON, 2f, 2f), GameConVars.OFFLINE_MAP_BUTTON, bl, tr, false);
					button.setData(map);
					mapButtons[i] = button;
				}
			}
		}
		j++;
		
		numOfAvailabeMaps = j;
		

		mBackground = new Image(GameConVars.MENUBACKGROUND,mGLWidth, mGLHeight);
	}

	public void draw(GL10 gl){
		mBackground.draw(gl, Camera.GL_WIDTH/2,Camera.GL_HEIGHT/2);
		for(PressableButton b: mapButtons){
			if(b!=null){
				b.draw(gl);
			}
		}
		
		loadOnlineMapsButton.draw(gl);
	}

	private String[] getOfflineMaps(){

		String[] mapNames = new String[maxMaps];

		int i = 0;
		for(Field f: R.raw.class.getFields()){
			if(f.getName().startsWith("map")){
				mapNames[i]= f.getName();
				++i;
			}
		}

		return mapNames;
	}

	private String[] getOnlineMaps(){
		//TODO:  need a wait here, in case online call takes a little longer
		WebServiceProvider wsp = new WebServiceProvider();
		return wsp.getMapsFromServer();
	}

	private int getResourceId(String mapName){
		int resId = -1;
		try {
			resId =  R.raw.class.getField(mapName).getInt(null);
		} catch (Exception e){
			Logger.e(e);
		}
		return resId;
	}

	public void handleTouch(PointF glLocation) throws Exception{
		for(PressableButton b: mapButtons){
			if(b!=null && b.insideBox(glLocation)){
				
				
				
				
				if(b.getData() instanceof Integer){
					int mapID = (Integer)b.getData();
					if(mapID >=0){
						dispose();
						mGame.start(GameConVars.GAME_LOCAL,true, mapID);
					}else{
						Logger.popUp("Unable to load map");
					}
				}else{
					String map = (String)b.getData();
					dispose();
					mGame.start(GameConVars.GAME_LOCAL,true, map);
				}
			}
		}
		
		if(loadOnlineMapsButton.insideBox(glLocation)){
			onlineMaps = getOnlineMaps();	
			loadOnlineMapsButton.setVisibility(true);
			setUpOnlineMapsButton();
		}
	}

	private void setUpOnlineMapsButton(){
		if(onlineMaps != null){
			for(int i = 0; i < onlineMaps.length; i++){
				String map = onlineMaps[i];
				if(map != null){
					PointF bl = buttonLocations[numOfAvailabeMaps];
					PointF tr = new PointF(bl.x +2, bl.y +2);
					PressableButton button = new PressableButton(new Image(GameConVars.ONLINE_MAP_BUTTON, 2f, 2f), GameConVars.OFFLINE_MAP_BUTTON, bl, tr, false);
					button.setData(map);
					mapButtons[numOfAvailabeMaps] = button;
					numOfAvailabeMaps++;
				}
			}
		}
	}
	
	private void dispose(){
		//TODO:  clear all map data 
		if(offlineMaps != null){
			for(int i = 0; i < offlineMaps.length; i++){
				offlineMaps[i] = null;
			}
			offlineMaps = null;
		}
		if(onlineMaps != null){
			for(int i = 0; i < onlineMaps.length; i++){
				onlineMaps[i] = null;
			}
			onlineMaps = null;
		}

	}
}
